package net.cyue.easyconfiguration.node.util;

import net.cyue.easyconfiguration.node.NodeType;
import net.cyue.easyconfiguration.node.definition.AbstractNodeDefinition;
import net.cyue.easyconfiguration.node.definition.ArrayNodeDefinition;
import net.cyue.easyconfiguration.node.definition.TableNodeDefinition;

import java.util.HashMap;
import java.util.Map;

public class NodeValueProcesser {

    // TODO 特殊化处理 wildcard path

    /**
     * 处理数组数据，转换所有 nodeValue
     * @param definition 节点定义
     * @param array 读取后未处理的数组数据
     * @return 处理后的数组
     */
    public static Object processArray(
        ArrayNodeDefinition definition,
        Object[] array
    ) {
        if (array == null || array.length == 0) {
            return array;
        }
        return NodeValueConverter.convertNodeValue(definition, array);
    }

    /**
     * 处理表值，将字段名映射为 nodeName，并转换所有 nodeValue
     * @return 处理后的表
     */
    public static Object processTable(
        TableNodeDefinition definition,
        Map<String, Object> map
    ) {
        if (map == null || map.isEmpty()) {
            return map;
        }

        // 将 字段名 处理为 节点名称
        Map<String, Object> table = new HashMap<>();
        for (AbstractNodeDefinition fieldDefinition : definition.getFieldDefinitions()) {
            for (String fPath : fieldDefinition.getPaths()) {
                Object value = map.get(fPath);
                if (value != null) {
                    table.put(fieldDefinition.getName(), value);
                }
            }
        }
        return NodeValueConverter.convertNodeValue(definition, table);
    }

    /**
     * 处理 nodeValue
     * @param definition
     * @param value
     * @return
     */
    public static Object processNodeValue(
        AbstractNodeDefinition definition,
        Object value
    ) {
        if (value == null) {
            return null;
        }

        if (definition.getType() == NodeType.ARRAY) {
            if (value.getClass().isArray()) {
                return processArray(
                    (ArrayNodeDefinition) definition,
                    (Object[]) value
                );
            } else {
                return processArray(
                    (ArrayNodeDefinition) definition,
                    new Object[] { value }
                );
            }
        } else if (
            definition.getType() == NodeType.TABLE &&
            value instanceof Map
        ) {
            return processTable(
                (TableNodeDefinition) definition,
                (Map<String, Object>) value
            );
        }
        // 默认转换
        return NodeValueConverter.convertNodeValue(definition, value);
    }
}

